const https = require('https');
const http = require('http');
const request = require('request');
const cheerio = require('cheerio');
const fs = require('fs');
const ca = fs.readFileSync('./cert/srca.cer.pem');
const nodemailer = require('nodemailer');
const schedule = require('node-schedule');
const scanf = require('scanf');
const program = require('commander');
const UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3680.0 Safari/537.36";
const inquirer = require('inquirer');
const config = require('./config');
let $;
var prompt = inquirer.createPromptModule();
let _stations = JSON.parse(fs.readFileSync('station.json', 'utf-8'));
let isRewrite = hasArgv(process.argv, '-r');
let isUpdateStation = hasArgv(process.argv, '-t');
function hasArgv(argv, filter) {
	argv = argv.slice(2);
	return argv.some((item, i) => {
		return filter === item;
	});
}
let startStations = {
	lists: [],
	origin: {}
};
let endStations = {
	lists: [],
	origin: {}
};
function searchTrain(answers, input) {
	input = input || '';
	console.log(input);
	return;
	if (Object.prototype.toString.call(_stations.stationInfo[input]) === '[object Array]') {

	}
	else {

	}
}

function getLeftTicketUrl(callback) {
	request.get("https://kyfw.12306.cn/otn/leftTicket/init", (e, r, b) => {
		const defaultUrl = 'leftTicket/queryZ';
		if (e) {
			callback && callback({ leftTicketUrl: defaultUrl });
			console.log(e);
			return;
		}
		$ = cheerio.load(r.body, { decodeEntities: false });
		let pageHtml = $.html();
		let re = pageHtml.match(/var CLeftTicketUrl = '\w+\/\w+/ig);
		let leftTicketUrl;

		if (re && re.length) {
			leftTicketUrl = re[0].replace(/var CLeftTicketUrl = \'/, '');

			if (!leftTicketUrl) {
				leftTicketUrl = defaultUrl;
			}
		}
		else {
			leftTicketUrl = defaultUrl;
		}
		callback && callback({ leftTicketUrl: leftTicketUrl });
	});
}

// 解密
function b4(ct, cv) {
	var cs = [];
	for (var cr = 0; cr < ct.length; cr++) {
		var cw = [];
		var cq = ct[cr].split("|");
		cw.secretHBStr = cq[36];
		cw.secretStr = cq[0];
		cw.buttonTextInfo = cq[1];
		var cu = [];
		cu.train_no = cq[2];
		cu.station_train_code = cq[3];
		cu.start_station_telecode = cq[4];
		cu.end_station_telecode = cq[5];
		cu.from_station_telecode = cq[6];
		cu.to_station_telecode = cq[7];
		cu.start_time = cq[8];
		cu.arrive_time = cq[9];
		cu.lishi = cq[10];
		cu.canWebBuy = cq[11];
		cu.yp_info = cq[12];
		cu.start_train_date = cq[13];
		cu.train_seat_feature = cq[14];
		cu.location_code = cq[15];
		cu.from_station_no = cq[16];
		cu.to_station_no = cq[17];
		cu.is_support_card = cq[18];
		cu.controlled_train_flag = cq[19];
		cu.gg_num = cq[20] ? cq[20] : "--";
		// 高级软卧
		cu.gr_num = cq[21] ? cq[21] : "--";
		// 其他
		cu.qt_num = cq[22] ? cq[22] : "--";
		// 软卧
		cu.rw_num = cq[23] ? cq[23] : "--";
		// 软座
		cu.rz_num = cq[24] ? cq[24] : "--";
		cu.tz_num = cq[25] ? cq[25] : "--";
		// 无座
		cu.wz_num = cq[26] ? cq[26] : "--";
		cu.yb_num = cq[27] ? cq[27] : "--";
		// 硬卧
		cu.yw_num = cq[28] ? cq[28] : "--";
		// 硬座
		cu.yz_num = cq[29] ? cq[29] : "--";
		// 二等座
		cu.ze_num = cq[30] ? cq[30] : "--";
		// 一等座
		cu.zy_num = cq[31] ? cq[31] : "--";
		// 商务座
		cu.swz_num = cq[32] ? cq[32] : "--";
		// 动卧
		cu.srrb_num = cq[33] ? cq[33] : "--";
		cu.yp_ex = cq[34];
		cu.seat_types = cq[35];
		cu.exchange_train_flag = cq[36];
		cu.from_station_name = cv[cq[6]];
		cu.to_station_name = cv[cq[7]];
		cw.queryLeftNewDTO = cu;
		cs.push(cw)
	}
	return cs
}


var yz_temp = [], yw_temp = [];//保存余票状态


//  邮箱发送
function sendMail(mailOptions) {
	/*设置邮箱信息*/
	var transporter = nodemailer.createTransport({
		host: "smtp.163.com",//邮箱的服务器地址，如果你要换其他类型邮箱（如QQ）的话，你要去找他们对应的服务器，
		secureConnection: true,
		port: config.email.port,//端口，这些都是163给定的，自己到网上查163邮箱的服务器信息
		auth: {
			user: config.email.your_mail,//邮箱账号
			pass: config.email.mail_pass,//邮箱密码
		}
	});

	// 发邮件部分
	(function () {
		transporter.sendMail(mailOptions, function (error, info) {
			if (error) {
				return console.log(error);
			}
			console.log(' 邮件已发送: ====================> ' + mailOptions.to);

		});
	})();
}
/*
* 查询余票
*/
function queryTickets(config) {
	/*设置请求头参数*/
	let leftTicketUrl = config.leftTicketUrl;
	let url = '/otn/' + leftTicketUrl + '?leftTicketDTO.train_date=' + config.time + '&leftTicketDTO.from_station=' + config.from_station.code + '&leftTicketDTO.to_station=' + config.end_station.code + '&purpose_codes=' + config.ticket_type
	console.log('当前请求的地址：', 'https://kyfw.12306.cn' + url);
	var options = {
		hostname: 'kyfw.12306.cn',//12306
		port: 443,
		method: 'GET',
		path: url,
		ca: [ca],//证书
		rejectUnauthorized: false,
		headers: {
			"Accept": "*/*",
			'Connection': 'keep-alive',
			'Host': 'kyfw.12306.cn',
			'User-Agent': UA,
			"Connection": "keep-alive",
			"Referer": "https://kyfw.12306.cn/otn/leftTicket/init",
			"If-Modified-Since": "0",
			"X-Requested-With": "XMLHttpRequest",
			"Cookie": "JSESSIONID=A148DD650B5FA595DCC6838375CC1908; _jc_save_wfdc_flag=dc; route=495c805987d0f5c8c84b14f60212447d; BIGipServerotn=401080586.64545.0000; acw_tc=AQAAADUPbiLlcgsAuLz+Z7yML4078ek+; BIGipServerpool_passport=334299658.50215.0000; RAIL_EXPIRATION=1516454884979; RAIL_DEVICEID=qZf4Jpki03x17e3hoZ1td3gIxLrh3ktcodtRqpODJdH0J-WB98EoFETG8NNJC-YXQIDd4wA6DD4CP5YhHvU6WrxKIiEDgvcTnhaj9ZvFkoAulVhEWzTXFP0O1VXy5nf24YuP23pxRskcdaaviMsDkCSMZgGwWQWC; _jc_save_toDate=2018-01-18; _jc_save_fromStation=%u5317%u4EAC%2CBJP; _jc_save_toStation=%u5408%u80A5%2CHFH; _jc_save_fromDate=2018-02-01",
		}
	};

	/*请求开始*/
	var req = https.get(options, function (res) {
		console.log("statusCode: ", res.statusCode);
		var data = '';

		res.on('data', function (buff) {

			data += buff;//查询结果（JSON格式）
		});
		res.on('end', function () {
			var jsonData;
			var trainData;
			//用来保存返回的json数据

			var trainMap;
			if (!data) {
				console.log("数据为空-------")
				return
			}
			try {
				var _data = JSON.parse(data).data;
				trainData = _data && _data.result;
				trainMap = _data && _data.map;
			} catch (e) {
				console.log('JSON数据出错,请检查输入配置是否正确', e);
				console.log('出错的数据：', data);
				return;
			}
			jsonData = b4(trainData, trainMap);
			// console.log("jsonData", jsonData)
			if (!jsonData || jsonData.length == 0) {
				console.log('没有查询到余票信息');
				return;
			}
			/*获取车次与车辆代码的映射表*/
			var jsonMap = {};
			for (var i = 0; i < jsonData.length; i++) {
				var cur = jsonData[i];
				jsonMap[cur.queryLeftNewDTO.station_train_code] = cur.queryLeftNewDTO;

			}
			/*过滤不需要的车次*/
			var train_arr = config.train_num;
			for (var j = 0; j < train_arr.length; j++) {
				var cur_train = jsonMap[train_arr[j]];//当前车次
				if (!cur_train) {
					console.log('当天没有' + train_arr[j] + '这趟车次');
					continue;
				}
				let trains = {
					'高级软卧': cur_train.gr_num,
					// 其他
					'其他': cur_train.qt_num,
					// 软卧
					'软卧': cur_train.rw_num,
					// 软座
					'软座': cur_train.rz_num,
					// 无座
					'无座': cur_train.wz_num,
					// 硬卧
					'硬卧': cur_train.yw_num,
					// 硬座
					'硬座': cur_train.yz_num,
					// 二等座
					'二等座': cur_train.ze_num,
					// 一等座
					'一等座': cur_train.zy_num,
					// 商务座
					'商务座': cur_train.swz_num,
					// 动卧
					'动卧': cur_train.srrb_num
				}
				const selectType = config.selectType;

				var trainNum = cur_train.station_train_code;//车次
				// 暂存信息
				let remain = {
					trains: "",
					typeAndNum: [],
					isOk: false
				}
				selectType.forEach(item => {
					if (trains[item] != '无' && trains[item] != '--') {
						remain.trains = trainNum;
						remain.typeAndNum.push(`${item} : ${trains[item]}`);
						if (!remain.isOk) {
							remain.isOk = true;
						}
					}
				})
				// 判断是否有票
				if (remain.isOk) {
					let presentData = remain.typeAndNum.join(',')
					if (yw_temp[j] == presentData) {
						console.log(' ' + trainNum + '车次状态没改变，不重复发邮件');
						continue;
					}

					var mailOptions = {
						from: config.email.your_mail, // 发件邮箱地址
						to: config.email.to, // 收件邮箱地址，可以和发件邮箱一样
						subject: remain.trains + presentData, // 邮件标题
						text: ' hi!\n' + trainNum + '有票啦\n' + cur_train.from_station_name + '=============>' + cur_train.to_station_name + '\n出发日期：' + config.time + ',\n出发时间：' + cur_train.start_time + ',\n到达时间：' + cur_train.arrive_time + ',\n历时：' + cur_train.lishi, // 邮件内容
					};
					console.log(mailOptions.text)
					postSendDing(mailOptions)
					// sendMail(mailOptions)

					yw_temp[j] = presentData;

				} else {
					console.log(trainNum + selectType.join(','), "无票","time>>>: "+getTime());
				}

			}
			// fs.writeFile('./train.json',data);
		});
	});

	req.on('error', function (err) {
		console.error(err.code);
	});
}

/*
* 爬取全国车站信息并生成JSON文件
*/
function stationJson() {
	// ?station_version=1.9044
	let _opt = {
		hostname: 'kyfw.12306.cn',
		path: '/otn/resources/js/framework/station_name.js?station_version=1.9091',
		ca: [ca],
		rejectUnauthorized: false
	};
	let _data = '';
	let _req = https.get(_opt, function (res) {

		res.on('data', function (buff) {
			_data += buff;
		});
		res.on('end', function () {
			console.log(_data + '\n如果前面的信息不是车站信息，那就说明没有抓取成功，可能需要升级一下station_version');
			try {
				let re = /\|[\u4e00-\u9fa5]+\|[A-Z]{3}\|\w+\|\w+\|\w+@\w+/g;
				// console.log('data',_data.match(re));
				let stationMap = {};
				let stationArray = [];
				let temp = _data.match(re);
				[].forEach.call(temp, function (item, i) {
					// console.log(item,i);
					let t = item.split("|");
					let info = {
						name: t[1],
						code: t[2],
						pinyin: t[3],
						suoxie: t[4],
						other: t[5]
					};
					stationArray.push(t[3]);
					if (!stationMap[t[3]]) {
						stationMap[t[3]] = info;
					}
					else {
						if (Object.prototype.toString.call(stationMap[t[3]]) === '[object Array]') {
							stationMap[t[3]] = [...stationMap[t[3]], info];
						}
						else {
							stationMap[t[3]] = [stationMap[t[3]], info];
						}
					}
				});
				let jsonStationMap = {
					stationName: stationArray,
					stationInfo: stationMap
				}
				fs.writeFile('station.json', JSON.stringify(jsonStationMap), function (err) {
					if (err) throw err;
					console.log('成功更新车站信息！');
				});
				console.log('成功更新车站信息！');
			} catch (e) {
				console.log('更新车站信息失败：', e);
				return null;
			}
		});
	});
	_req.on('error', function (err) {
		console.error(err.code);
	});
}
function getTime() {
	let T = new Date();
	return T.getFullYear() + '-' + (parseInt(T.getMonth()) + 1) + '-' + T.getDate() + ' ' + T.getHours() + ":" + T.getMinutes() + ":" + T.getSeconds();
}

// stationJson()
// 钉钉推送消息
function postSendDing(msgData = {}) {
	let options = {
		hostname: 'oapi.dingtalk.com',
		port: 443,
		method: 'POST',
		path: `/robot/send?access_token=${config.access_token}`,
		headers: {
			"Content-Type": "application/json"
		}
	};
	const content = {
		"msgtype": "text",
		"text": {
			"title": "我的消息",
			"content": `@13161969400  ${msgData.text}`
		},
		"at": {
			"atMobiles": [
				"13161969400"
			],
			"isAtAll": false
		}
	}
	let reqs = https.request(options, function (res) {
		console.log("statusCode: ", res.statusCode);
		let _data = '';
		res.on('data', function (chunk) {
			_data += chunk;
		});
		res.on('end', function () {
			console.log("通知成功:", _data)
		});
	})

	reqs.on('error', e => {
		console.log("推送消息错误:", e)
	})

	reqs.write(JSON.stringify(content));
	reqs.end();
}


setInterval(() => {
	queryTickets(config)
}, 2 * 1000 * 60)

queryTickets(config)